package edu.neumont.pro180._2009_q2.chess;

import java.awt.Point;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import edu.neumont.pro180._2009_q2.GamePiece;
import edu.neumont.pro180._2009_q2.Square;

public abstract class LinearlyMovingPiece extends GamePiece {
	protected static boolean isCaptureEnabled = true;
	
	

	@Override
	public abstract Collection<Square> getPossibleSquares();

	/**
	 * Fills a collection with all the available moves in a given direction.
	 * 
	 * @param startingSquare
	 *            The starting square to use for gathering available moves.
	 * @param vector
	 *            The direction in which to search for available moves.
	 * @param includeCaptureSquares
	 *            Whether to include squares with pieces (capturable squares) in
	 *            the collection of available moves.
	 * @param maxDistance
	 *            The maximum distance that a piece is allowed to travel for a
	 *            move. Use -1 for pieces that don't have a maximum distance
	 *            constraint.
	 * @param toFill
	 *            The collection that will hold the available moves.
	 */
	protected void collectSquaresInLine(Square startingSquare, Point vector,
			boolean includeCaptureSquares, int maxDistance,
			Collection<Square> toFill) {
		if (maxDistance != 0) {
			Square neighbor = startingSquare.getNeighbor(vector);
			if (neighbor != null) {
				if (neighbor.hasGamePiece()) {
					if (this.getPlayer() != neighbor.getGamePiece().getPlayer()) {
						if (includeCaptureSquares) {
							toFill.add(neighbor);
						}
					}
				} else {
					toFill.add(neighbor);
					collectSquaresInLine(neighbor, vector,
							includeCaptureSquares, maxDistance - 1, toFill);
				}
			}
		}
	}

	/**
	 * Returns the diagonal Squares surrounding the piece. It's a private
	 * function to help with checker movement.
	 * 
	 * @param startingSquare
	 *            The Square to start at.
	 * @param maxDistance
	 *            The maximum number of squares that a piece can move. -1 for
	 *            unbounded.
	 * @return The set of Squares diagonally around the startingSquare.
	 */
	protected Collection<Square> getDiagonals(Square startingSquare,
			int maxDistance) {
		Set<Square> possibleMoves = new HashSet<Square>();
		collectSquaresInLine(startingSquare, new Point(1, 1), isCaptureEnabled,
				maxDistance, possibleMoves);
		collectSquaresInLine(startingSquare, new Point(1, -1),
				isCaptureEnabled, maxDistance, possibleMoves);
		collectSquaresInLine(startingSquare, new Point(-1, 1),
				isCaptureEnabled, maxDistance, possibleMoves);
		collectSquaresInLine(startingSquare, new Point(-1, -1),
				isCaptureEnabled, maxDistance, possibleMoves);
		/*
		 * for (int x = -1; x < 2; x += 2) { for (int y = -1; y < 2; y += 2) {
		 * Square diagonalNeighbor = startingSquare.getNeighbor(new Point( x,
		 * y)); if (null != diagonalNeighbor) {
		 * possibleMoves.add(diagonalNeighbor); } } }
		 */
		return possibleMoves;
	}

	protected Collection<Square> getVerticalAndHorizontals(
			Square startingSquare, int maxDistance) {
		Set<Square> possibleMoves = new HashSet<Square>();
		collectSquaresInLine(startingSquare, new Point(0, 1), isCaptureEnabled,
				maxDistance, possibleMoves);
		collectSquaresInLine(startingSquare, new Point(1, 0), isCaptureEnabled,
				maxDistance, possibleMoves);
		collectSquaresInLine(startingSquare, new Point(0, -1),
				isCaptureEnabled, maxDistance, possibleMoves);
		collectSquaresInLine(startingSquare, new Point(-1, 0),
				isCaptureEnabled, maxDistance, possibleMoves);
		return possibleMoves;
	}
}